home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d982.lha / HWGRCS / HWGdiffP1_2_6.lha / diffutils-2.6 / src / fnmatch.c < prev    next >
C/C++ Source or Header  |  1993-12-18  |  6KB  |  215 lines

  1. /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public License as
  5. published by the Free Software Foundation; either version 2 of the
  6. License, or (at your option) any later version.
  7.  
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. Library General Public License for more details.
  12.  
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; see the file COPYING.LIB.  If
  15. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16. Cambridge, MA 02139, USA.  */
  17.  
  18. #ifdef HAVE_CONFIG_H
  19. #if defined (CONFIG_BROKETS)
  20. /* We use <config.h> instead of "config.h" so that a compilation
  21.    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
  22.    (which it would do because it found this file in $srcdir).  */
  23. #include <config.h>
  24. #else
  25. #include "config.h"
  26. #endif
  27. #endif
  28.  
  29. #include <errno.h>
  30. #include <fnmatch.h>
  31. #include <ctype.h>
  32.  
  33.  
  34. /* Comment out all this code if we are using the GNU C Library, and are not
  35.    actually compiling the library itself.  This code is part of the GNU C
  36.    Library, but also included in many other GNU distributions.  Compiling
  37.    and linking in this code is a waste when using the GNU C library
  38.    (especially if it is a shared library).  Rather than having every GNU
  39.    program understand `configure --with-gnu-libc' and omit the object files,
  40.    it is simpler to just do this in the source for each such file.  */
  41.  
  42. #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
  43.  
  44.  
  45. #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
  46. extern int errno;
  47. #endif
  48.  
  49. /* Match STRING against the filename pattern PATTERN, returning zero if
  50.    it matches, nonzero if not.  */
  51. int
  52. fnmatch (pattern, string, flags)
  53.      const char *pattern;
  54.      const char *string;
  55.      int flags;
  56. {
  57.   register const char *p = pattern, *n = string;
  58.   register char c;
  59.  
  60. #ifdef _AMIGA
  61. /* The Amiga has a case preserving but insensitive filesystem. That is why
  62.    we do not work case sensitive!
  63. */
  64.  
  65.   flags |= FNM_CASEFOLD;
  66. #endif
  67. /* Note that this evalutes C many times.  */
  68. #define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
  69.  
  70.   while ((c = *p++) != '\0')
  71.     {
  72.       c = FOLD (c);
  73.  
  74.       switch (c)
  75.         {
  76.         case '?':
  77.           if (*n == '\0')
  78.             return FNM_NOMATCH;
  79.           else if ((flags & FNM_FILE_NAME) && *n == '/')
  80.             return FNM_NOMATCH;
  81.           else if ((flags & FNM_PERIOD) && *n == '.' &&
  82.                    (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
  83.             return FNM_NOMATCH;
  84.           break;
  85.  
  86.         case '\\':
  87.           if (!(flags & FNM_NOESCAPE))
  88.             {
  89.               c = *p++;
  90.               c = FOLD (c);
  91.             }
  92.           if (FOLD (*n) != c)
  93.             return FNM_NOMATCH;
  94.           break;
  95.  
  96.         case '*':
  97.           if ((flags & FNM_PERIOD) && *n == '.' &&
  98.               (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
  99.             return FNM_NOMATCH;
  100.  
  101.           for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  102.             if (((flags & FNM_FILE_NAME) && *n == '/') ||
  103.                 (c == '?' && *n == '\0'))
  104.               return FNM_NOMATCH;
  105.  
  106.           if (c == '\0')
  107.             return 0;
  108.  
  109.           {
  110.             char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  111.             c1 = FOLD (c1);
  112.             for (--p; *n != '\0'; ++n)
  113.               if ((c == '[' || FOLD (*n) == c1) &&
  114.                   fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
  115.                 return 0;
  116.             return FNM_NOMATCH;
  117.           }
  118.  
  119.         case '[':
  120.           {
  121.             /* Nonzero if the sense of the character class is inverted.  */
  122.             register int not;
  123.  
  124.             if (*n == '\0')
  125.               return FNM_NOMATCH;
  126.  
  127.             if ((flags & FNM_PERIOD) && *n == '.' &&
  128.                 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
  129.               return FNM_NOMATCH;
  130.  
  131.             not = (*p == '!' || *p == '^');
  132.             if (not)
  133.               ++p;
  134.  
  135.             c = *p++;
  136.             for (;;)
  137.               {
  138.                 register char cstart = c, cend = c;
  139.  
  140.                 if (!(flags & FNM_NOESCAPE) && c == '\\')
  141.                   cstart = cend = *p++;
  142.  
  143.                 cstart = cend = FOLD (cstart);
  144.  
  145.                 if (c == '\0')
  146.                   /* [ (unterminated) loses.  */
  147.                   return FNM_NOMATCH;
  148.  
  149.                 c = *p++;
  150.                 c = FOLD (c);
  151.  
  152.                 if ((flags & FNM_FILE_NAME) && c == '/')
  153.                   /* [/] can never match.  */
  154.                   return FNM_NOMATCH;
  155.  
  156.                 if (c == '-' && *p != ']')
  157.                   {
  158.                     cend = *p++;
  159.                     if (!(flags & FNM_NOESCAPE) && cend == '\\')
  160.                       cend = *p++;
  161.                     if (cend == '\0')
  162.                       return FNM_NOMATCH;
  163.                     cend = FOLD (cend);
  164.  
  165.                     c = *p++;
  166.                   }
  167.  
  168.                 if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
  169.                   goto matched;
  170.  
  171.                 if (c == ']')
  172.                   break;
  173.               }
  174.             if (!not)
  175.               return FNM_NOMATCH;
  176.             break;
  177.  
  178.           matched:;
  179.             /* Skip the rest of the [...] that already matched.  */
  180.             while (c != ']')
  181.               {
  182.                 if (c == '\0')
  183.                   /* [... (unterminated) loses.  */
  184.                   return FNM_NOMATCH;
  185.  
  186.                 c = *p++;
  187.                 if (!(flags & FNM_NOESCAPE) && c == '\\')
  188.                   /* XXX 1003.2d11 is unclear if this is right.  */
  189.                   ++p;
  190.               }
  191.             if (not)
  192.               return FNM_NOMATCH;
  193.           }
  194.           break;
  195.  
  196.         default:
  197.           if (c != FOLD (*n))
  198.             return FNM_NOMATCH;
  199.         }
  200.  
  201.       ++n;
  202.     }
  203.  
  204.   if (*n == '\0')
  205.     return 0;
  206.  
  207.   if ((flags & FNM_LEADING_DIR) && *n == '/')
  208.     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
  209.     return 0;
  210.  
  211.   return FNM_NOMATCH;
  212. }
  213.  
  214. #endif  /* _LIBC or not __GNU_LIBRARY__.  */
  215.